package com.gjy.util.encryption.digest;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.Security;

/**
 * @author 宫静雨
 * @version 1.0
 * @since 2022-11-08 11:12:22
 */
public class DigestCoder {

    public DigestCoder() {
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * @see MD
     * @see SHA
     */
    public byte[] encryptDigest(byte[] data, String sign) {
        try {
            MessageDigest digest = MessageDigest.getInstance(sign);
            return digest.digest(data);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 加盐处理
     */
    public byte[] encryptDigest(byte[] data, byte[] salt, String sign) {
        byte[] res = new byte[data.length + salt.length];
        System.arraycopy(data, 0, res, 0, data.length);
        System.arraycopy(salt, 0, res, data.length, salt.length);
        return encryptDigest(res, sign);
    }

    public byte[] encryptDigest(byte[] data, byte[] salt, int size, String sign) {
        byte[] res = new byte[data.length + salt.length];
        System.arraycopy(data, 0, res, 0, data.length);
        System.arraycopy(salt, 0, res, data.length, salt.length);

        for (int i = 0; i < size; i++) {
            res = encryptDigest(res, salt, sign);
        }
        return res;
    }

    /**
     * @see MAC
     */
    public byte[] encryptMac(byte[] data, String sign) {
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance(sign);
            byte[] key = keyGenerator.generateKey().getEncoded();

            SecretKeySpec keySpec = new SecretKeySpec(key, sign);
            Mac mac = Mac.getInstance(keySpec.getAlgorithm());
            mac.init(keySpec);
            return mac.doFinal(data);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 加盐处理
     */
    public byte[] encryptMac(byte[] data, byte[] salt, String sign) {
        byte[] res = new byte[data.length + salt.length];
        System.arraycopy(data, 0, res, 0, data.length);
        System.arraycopy(salt, 0, res, data.length, salt.length);
        return encryptMac(res, sign);
    }

    public byte[] encryptMac(byte[] data, byte[] salt, int size, String sign) {
        byte[] res = new byte[data.length + salt.length];
        System.arraycopy(data, 0, res, 0, data.length);
        System.arraycopy(salt, 0, res, data.length, salt.length);

        for (int i = 0; i < size; i++) {
            res = encryptMac(res, salt, sign);
        }
        return res;
    }

    public interface MD {
        String MD_2 = "MD2";
        String MD_4 = "MD4";
        String MD_5 = "MD5";
    }

    public interface SHA {
        String SHA_1 = "SHA1";
        String SHA_224 = "SHA224";
        String SHA_256 = "SHA256";
        String SHA_384 = "SHA384";
        String SHA_512 = "SHA512";
    }

    public interface MAC {
        String H_MAC_MD2 = "HmacMD2";
        String H_MAC_MD4 = "HmacMD4";
        String H_MAC_MD5 = "HmacMD5";
        String H_MAC_SHA1 = "HmacSHA1";
        String H_MAC_SHA224 = "HmacSHA224";
        String H_MAC_SHA256 = "HmacSHA256";
        String H_MAC_SHA384 = "HmacSHA384";
        String H_MAC_SHA512 = "HmacSHA512";
    }
}
